//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<CCanvasTextBoard.cpp>
///	@path	~/src/graphics/canvas/
///	@date	2007/12/24
///	@desc	.

#include "config/config.h"

#include "graphics/IFont.h"
#include "graphics/DxMath.h"
#include "graphics/dx9/CFont9.h"
#include "graphics/dx10/CFont10.h"
#include "graphics/canvas/CCanvasTextBoard.h"

namespace xeres {

	IMPL_IOBJECT_CLASS( CCanvasTextBoard );

	// CCanvasTextBoard
	CCanvasTextBoard::CCanvasTextBoard( RefWeak<IFont> font , std::deque<TextBoardLine> * lines )
		: m_startingLine( 0 )
		, m_spacing( 2 )
		, m_font( font )
		, m_lines( lines )
		, m_rect( 0 , 0 , 0 , 0 )
	{
	}

	// ~CCanvasTextBoard
	CCanvasTextBoard::~CCanvasTextBoard( void )
	{
	}

	// Render
	void CCanvasTextBoard::Render( RenderContext& rc , RefWeak<ISprite> sprite )
	{
		TRACK_FUNCTION_SCOPE();

		if( m_lines->empty() )
			return;

		// get device context
		HDC dc = NULL;
		if( m_font->IsA<CFont9>() )
		{
			RefWeak<CFont9> font = m_font;
			dc = font->GetFont()->GetDC();
		}
		else
		{
			RefWeak<CFont10> font = m_font;
			dc = font->GetFont()->GetDC();
		}

		LockGuard<ThreadLock> s_locker( m_lock );
		if( m_rect.width() == 0 || m_rect.height() == 0 )
		{
			m_rect.set( 0 , 0 , rc.ResX<int>() , rc.ResY<int>() );
		}

		// draw lines
		Rect<int> rect( m_rect );

		size_t i = 0;
		for( ; i < (size_t)m_startingLine ; ++i )
		{
			(*m_lines)[i].top = (*m_lines)[i].bottom = -1;
		}
		for( size_t total = m_lines->size() ; i < total ; ++i )
		{
			if( !DrawLine( (*m_lines)[i] , rect , sprite , dc ) )
				break;
		}
		for( size_t total = m_lines->size() ; i < total ; ++i )
		{
			(*m_lines)[i].top = (*m_lines)[i].bottom = -1;
		}
	}

	// SetRect
	void CCanvasTextBoard::SetRect( const Rect<int>& rect )
	{
		m_rect = rect;
	}

	// DrawLine
	bool CCanvasTextBoard::DrawLine( TextBoardLine& line , Rect<int>& rect , RefWeak<ISprite> sprite , HDC dc )
	{
		// calculate rectangle
		int width = rect.width();
		int height = rect.height();
		RECT rc = { 0 , 0 , width , 0 };
		size_t count = line.line.size();
		if( line.line[line.line.size()-1] == '\n' )
			--count;
		DrawText( dc , line.line.c_str() , (int)count , &rc , DT_CALCRECT | DT_TOP | DT_LEFT | DT_SINGLELINE );

		int next_top = rect.top() + rc.bottom + m_spacing;

		if( next_top < rect.bottom() )
		{
			int r[4] = { rect.left() , rect.top() , rect.right() , rect.bottom() };

			line.top = rect.top();
			line.bottom = next_top;

			// try to draw text
			m_font->DrawText( sprite , line.line.c_str() , r , DT_TOP | DT_LEFT | DT_WORDBREAK , line.color );

			rect.set( rect.left() , next_top , rect.right() , rect.bottom() );
			return true;
		}
		else
		{
			return false;
		}
	}

} // namespace xeres
